package com.xq.pay;

import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.demo.trade.config.Configs;
import com.alipay.demo.trade.model.builder.AlipayTradePayRequestBuilder;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.builder.AlipayTradeRefundRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPayResult;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.model.result.AlipayF2FRefundResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author： XQ
 * @Description： 支付类
 * @Created-Date：2020年10月02日 13时55分05秒
 */
public class PayService {
    /**
     *  日志处理
     */
    static Log log = LogFactory.getLog("PayService");

    /**
     * 支付宝当面付的对象
     */
    static AlipayTradeService tradeService;

    static {
        // 一定要在创建AlipayTradeService之前调用Configs.init设置默认参数
        // AlipayTradeService可以使用单例或者为静态成员对象，不需要反复new
        Configs.init("zfbinfo.properties");
        tradeService = new AlipayTradeServiceImpl.ClientBuilder().build();
    }

    /**
     * 商户操作员编号，添加此参数可以为商户操作员做销售统计
     */
    static String operatorId = "test_operator_id";

    /**
     * (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
     */
    static String storeId = "test_store_id";

    /**
     * 支付超时，线下扫码交易定义为120分钟
     */
    static String timeoutExpress = "120m";

    /**
     * 支付方法
     * @param outTradeNo (必填) 商户网站订单系统中唯一订单号
     * @param subject  (必填) 订单标题，粗略描述用户的支付目的
     * @param totalAmount (必填) 订单总金额，单位为元，不能超过1亿元
     * @param undiscountableAmount (可选) 订单不可打折金额，可以配合商家平台配置折扣活动
     * @param body 订单描述，可以对交易或商品进行一个详细地描述
     * @param notifyUrl 支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
     * @return
     */
    public static Map<String, Object> pay(String outTradeNo,
                                          String subject,
                                          String totalAmount,
                                          String undiscountableAmount,
                                          String body,
                                          String notifyUrl) {
        // 创建请求builder，设置请求参数
        AlipayTradePrecreateRequestBuilder builder =new AlipayTradePrecreateRequestBuilder()
                .setSubject(subject)
                .setTotalAmount(totalAmount)
                .setOutTradeNo(outTradeNo)
                .setUndiscountableAmount(undiscountableAmount)
                .setBody(body)
                .setOperatorId(operatorId)
                .setStoreId(storeId)
                .setTimeoutExpress(timeoutExpress)
              .setNotifyUrl(notifyUrl);

        // 调用tradePay方法获取当面付应答
        AlipayF2FPrecreateResult result = tradeService.tradePrecreate(builder);
        Map<String, Object> map = new HashMap<>(16);
        String msg ;
        Integer code ;
        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("支付宝支付成功: ");
                AlipayTradePrecreateResponse res = result.getResponse();
                // 得到支付二维码地址
                String qrCode = res.getQrCode();
                map.put("qrCode", qrCode);
                msg = "下单成功";
                code = 200;
                break;
            case FAILED:
                log.error("支付宝支付失败!!!");
                msg = "下单失败";
                code = 500;
                break;
            case UNKNOWN:
                log.error("系统异常，订单状态未知!!!");
                msg = "系统异常";
                code = 404;
                break;
            default:
                log.error("不支持的交易状态，交易返回异常!!!");
                msg = "不支持的交易状态";
                code = 404;
                break;
        }
        map.put("msg", msg);
        map.put("code", code);
        return map;
    }


    /**
     * 支付宝退费
     * @param outTradeNo 外部应用交易ID
     * @param tradeNo 平台在支付成功后的返回的平台的ID[属于支付宝平台的ID]
     * @param refundAmount 退款金额
     * @param refundReason 退款原因
     * @param outRequestNo 是否部分退款
     */
    public static Map<String, Object> payBack(String outTradeNo, String tradeNo, String refundAmount, String refundReason, String outRequestNo) {
        // outTradeNo和tradeNo只需要一个就行
        AlipayTradeRefundRequestBuilder builder = new AlipayTradeRefundRequestBuilder()
                .setOutTradeNo(outTradeNo)
                .setTradeNo(tradeNo)
                .setRefundAmount(refundAmount)
                .setRefundReason(refundReason)
                .setOutRequestNo(outRequestNo)
                .setStoreId(storeId);
        // 退费请求
        AlipayF2FRefundResult result = tradeService.tradeRefund(builder);
        Map<String, Object> map = new HashMap<>(16);
        String msg ;
        Integer code ;
        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("支付宝退款成功: )");
                code = 200;
                msg = "支付宝退款成功";
                map.put("tradeNo",result.getResponse().getTradeNo());
                break;

            case FAILED:
                log.error("支付宝退款失败!!!");
                code = 500;
                msg = "支付宝退款失败";
                break;

            case UNKNOWN:
                log.error("系统异常，订单退款状态未知!!!");
                code = 500;
                msg = "系统异常，订单退款状态未知";
                break;
            default:
                log.error("不支持的交易状态，交易返回异常!!!");
                code = 500;
                msg = "不支持的交易状态，交易返回异";
                break;
        }
        map.put("code", code);
        map.put("msg", msg);
        return map;
    }

}
